package service
{
	import flash.data.SQLResult;
	import flash.events.EventDispatcher;
	
	import localdb.dao.PageUpdateDAO;
	import localdb.table.PageUpdateTable;
	
	import model.Model;
	import model.Page;
	import model.PageUpdate;
	import model.PageUpdateFactory;
	
	import mx.collections.ArrayCollection;
	
	import asorm.db.LocalDatabase;
	import asorm.db.event.LocalDatabaseEvent;
	
	import wiki.event.WikiEvent;

	[Event(name="pageLoaded", type="wiki.event.WikiEvent")]
	[Event(name="pageIndexLoaded", type="wiki.event.WikiEvent")]
	public class LocalStorageService extends EventDispatcher implements StorageService {
		public function LocalStorageService() {
			_database = new LocalDatabase("airwiki");
			
			_pageUpdateTable = new PageUpdateTable(_database);
			_pageUpdateTable.create();
			
			_pageUpdateFactory = new PageUpdateFactory(_pageUpdateTable);
		}
		
		public function createPage(pageId:String=null): Page {
			return new Page(pageId);
		}
		
		public function loadPage(pageId: String): void {
			var sql: String = "SELECT * FROM " + _pageUpdateTable.name + " WHERE page_id = '" + pageId + "'";
			_pageUpdateTable.executeSQL(sql, loadPageHandler);
		}
		
		public function savePageUpdate(pageId: String, diffText: String): void {
			var pu:PageUpdate = _pageUpdateFactory.createPageUpdate(pageId, diffText);
			Model.instance.currentPage.addUpdate(pu);
			var dao: PageUpdateDAO = pu as PageUpdateDAO;
			dao.insert();			
		}
		
		public function disposePage(pageId: String): void {
		}
		
		public function loadPageIndex(): void {
			var sql: String = "SELECT DISTINCT page_id FROM " + _pageUpdateTable.name;
			_pageUpdateTable.executeSQL(sql, loadPageIndexHandler);
		}

		public function open(): void {
			_database.open();			
		}
		
		public function close(): void {
			_database.close();			
		}
		
		private function loadPageHandler(event:LocalDatabaseEvent): void {
			_pageUpdateTable.detachResultHandler(loadPageHandler);
			switch (event.queryType) {
				case LocalDatabaseEvent.QUERYTYPE_SELECT:
					var p: Page = new Page();
					p.addUpdates(convertSQLresultToPageUpdates(event.result));
					dispatchEvent(new WikiEvent(WikiEvent.PAGE_LOADED, p));	
				default:
					break;	
			}
		}
		
		private function loadPageIndexHandler(event:LocalDatabaseEvent): void {
			_pageUpdateTable.detachResultHandler(loadPageIndexHandler);
			switch (event.queryType) {
				case LocalDatabaseEvent.QUERYTYPE_SELECT:
					if (event.result != null && event.result.data != null) {
						dispatchEvent(new WikiEvent(WikiEvent.PAGEINDEX_LOADED, convertSQLresultToPageUpdates(event.result)));	
					}
				default:
					break;	
			}
		}
		
		private function convertSQLresultToPageUpdates(result: SQLResult): ArrayCollection {
			var updates: ArrayCollection = new ArrayCollection();
			var numRows: int = result==null||result.data==null ? 0 : result.data.length;
			for (var i:int=0; i<numRows; i++) {
				var dao: PageUpdateDAO = new PageUpdateDAO(_pageUpdateTable);
				dao.setPropertyValues(result.data[i]);
				updates.addItem(dao);
			}
			return updates;	
		}
		
		private var _pageUpdateFactory: PageUpdateFactory;
		private var _database: LocalDatabase;
		private var _pageUpdateTable: PageUpdateTable;
	}
}